package org.vaadin.nf4v.core.util;

import com.vaadin.ui.Component;
import org.vaadin.nf4v.core.navigation.NavigationManager;
import org.vaadin.nf4v.core.navigation.NavigationRequest;
import org.vaadin.nf4v.core.navigation.target.NavigationTarget;

import java.nio.channels.IllegalSelectorException;

/**
 * Simple utility class which allows easy request interruption.
 * Example use-cases:
 * 1. Interruption during security check (need to redirect to login page and after  successful login
 * process original navigation)
 * 2. Page leave warning: if page state is not saved request may be interrupted to ask user to allow navigation
 * <p/>
 * Note: implementation use NavigationFlash, so stored request will be available only for 2 navigations.
 */
public class NavigationInterruptor {
    public static final String INTERRUPTED_TARGET = "org.vaadin.nf4v.INTERRUPTED_TARGET";

    /**
     * Interrupts current request by cenceling it and storing navigation target in flash memory.
     * Interrupted request may be re-launched using continueInterrupted() method.
     *
     * @param request navigation request
     */
    public static void interrupt(NavigationRequest request) {
        request.cancel();
        NavigationManager.flash().put(INTERRUPTED_TARGET, request.getTarget());
    }

    /**
     * Executes interrupt(request) and navigates to provided page.
     *
     * @param request   navigation request
     * @param pageClass page class
     */
    public static void interruptAndRedirect(NavigationRequest request, Class<? extends Component> pageClass) {
        interrupt(request);
        NavigationManager.navigateTo(pageClass);
    }

    /**
     * Relaunches interrupted navigation.
     * @return true if interrupted target is still in flash memory and navigation continued, false otherwise 
     */
    public static boolean continueInterrupted(){
        NavigationTarget target = (NavigationTarget) NavigationManager.flash().remove(INTERRUPTED_TARGET);
        if (target == null) {
            return false;
        }
        NavigationManager.navigateTo(target);
        return true;
    }
}
